package net.minecraft.src;

public class TileEntityGrinder extends TileEntity
implements IInventory
{
	
	private ItemStack grinderStacks[];
	//The time the fuel is grinding
	public int grindTime;
	public int maxGrindTime;
	//The time the items are grinding
	public int itemGrindTime;
	//Is the grinder griding
	public boolean isGrinding;
	
	public TileEntityGrinder()
	{
		grinderStacks = new ItemStack[4];
		grindTime = 0;
		itemGrindTime = 0;
		maxGrindTime = 1;
		isGrinding = false;
	}
	
	// #region GUI
	public boolean isGrinding()
	{
		return grindTime > 0;
	}
	
	public int getCookProgressScaled(int i)
    {
        return (itemGrindTime * i) / 200;
    }

    public int getBurnTimeRemainingScaled(int i)
    {
        return 12 - (int)(((double)grindTime/(double)maxGrindTime)*i);
    }
    // #endregion

	@Override
	public int getSizeInventory()
	{
		return grinderStacks.length;
	}

	@Override
	public ItemStack getStackInSlot(int i)
	{
		return grinderStacks[i];
	}

	@Override
	public ItemStack decrStackSize(int i, int j)
	{
		if(grinderStacks[i] != null)
        {
            if(grinderStacks[i].stackSize <= j)
            {
                ItemStack itemstack = grinderStacks[i];
                grinderStacks[i] = null;
                return itemstack;
            }
            ItemStack itemstack1 = grinderStacks[i].splitStack(j);
            if(grinderStacks[i].stackSize == 0)
            {
            	grinderStacks[i] = null;
            }
            return itemstack1;
        } else
        {
            return null;
        }
	}

	public void setInventorySlotContents(int i, ItemStack itemstack)
    {
		grinderStacks[i] = itemstack;
        if(itemstack != null && itemstack.stackSize > getInventoryStackLimit())
            itemstack.stackSize = getInventoryStackLimit();
        if(!canContinueGrinding())
        {
        	itemGrindTime = 0;
        	isGrinding = false;
        }
    }

	@Override
	public String getInvName()
	{
		return "Grinder";
	}

	@Override
	public int getInventoryStackLimit()
	{
		return 64;
	}

	public boolean isUseableByPlayer(EntityPlayer entityplayer)
	{
		if(worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this)
			return false;
		return entityplayer.getDistanceSq(xCoord, yCoord, zCoord) < 64D;
	}

	public void openChest()
	{
	}

	public void closeChest()
	{
	}
	
	public void updateEntity()
	{
		/*
		 * 0 - Item A
		 * 1 - Item B
		 * 2 - Fuel A
		 * 3 - Result
		 */
		if(canGrindItem())
		{
			if(!isGrinding)
			{
				if(maxGrindTime == 1)
				{
					maxGrindTime = getGrindTime();
					changeSlotAmount(2, -1);
				}
			}
			isGrinding = true;
		}
		if(isGrinding)
		{
			if(!canContinueGrinding())
			{
				itemGrindTime = 0;
				isGrinding = false;
			}
		}
		if(isGrinding)
		{
			updateItemGrindTime();
			updateGrindTime();
		}
		else if(grindTime > 0)
			updateGrindTime();
	}
	
	private void updateItemGrindTime()
	{
		++itemGrindTime;
		if(itemGrindTime == 200)
		{
			grindItem();
			itemGrindTime = 0;
			if(!canGrindItem())
				isGrinding = false;
		}
	}
	
	private void updateGrindTime()
	{
		++grindTime;
		if(grindTime == maxGrindTime)
		{
			grindTime = 0;
			if(!hasItemInSlot(2))
			{
				isGrinding = false;
				itemGrindTime = 0;
				maxGrindTime = 1;
			}
			else
				changeSlotAmount(2, -1);
		}
	}
	
	private void grindItem()
	{
		if(hasItemInSlot(0) && hasItemInSlot(1)) //Combined Item
		{
			if(!hasItemInSlot(3))
				grinderStacks[3] = RecipesGrinder.getGrinder().getCombinedResult(getItemIdInSlot(0), getItemIdInSlot(1)).copy();
			else
				grinderStacks[3].stackSize += RecipesGrinder.getGrinder().getCombinedResult(getItemIdInSlot(0), getItemIdInSlot(1)).stackSize;
		}
		else if(hasItemInSlot(0))
		{
			if(!hasItemInSlot(3))
				grinderStacks[3] = RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(0)).copy();
			else
				grinderStacks[3].stackSize += RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(0)).stackSize;
		}
		else
		{
			if(!hasItemInSlot(3))
				grinderStacks[3] = RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(1)).copy();
			else
				grinderStacks[3].stackSize += RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(1)).stackSize;
		}
		if(hasItemInSlot(0))
			changeSlotAmount(0, -1);
		if(hasItemInSlot(1))
			changeSlotAmount(1, -1);
	}
	
	private void changeSlotAmount(int slot, int amount)
	{
		if(grinderStacks[slot] == null)
			return;
		grinderStacks[slot].stackSize += amount;
		if(grinderStacks[slot].stackSize <= 0)
			grinderStacks[slot] = null;
	}
	
	private ItemStack getResultItem()
	{
		if(hasItemInSlot(0) && hasItemInSlot(1)) //Combined Item
		{
			if(RecipesGrinder.getGrinder().getCombinedResult(getItemIdInSlot(0), getItemIdInSlot(1)) != null)
				return RecipesGrinder.getGrinder().getCombinedResult(getItemIdInSlot(0), getItemIdInSlot(1));
			else
				return null;
		}			
		else if(hasItemInSlot(0))
		{
			if(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(0)) != null)
				return RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(0));
			else
				return null;
		}
		else
		{
			if(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(1)) != null)
				return RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(1));
			else
				return null;
		}
	}
	
	private boolean canContinueGrinding()
	{
		if(hasItemInSlot(0) && hasItemInSlot(1)) //Combined Item
		{
			if(RecipesGrinder.getGrinder().getCombinedResult(getItemIdInSlot(0), getItemIdInSlot(1)) != null)
				return canGrindItem(RecipesGrinder.getGrinder().getCombinedResult(getItemIdInSlot(0), getItemIdInSlot(1)));
			else
				return false;
		}			
		else if(hasItemInSlot(0))
		{
			if(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(0)) != null)
				return canGrindItem(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(0)));
			else
				return false;
		}
		else
		{
			if(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(1)) != null)
				return canGrindItem(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(1)));
			else
				return false;
		}
	}
	
	private boolean canGrindItem() //Heeft item(s) + fuel
	{
		if(getGrindTime() == 1 && grindTime == 0)
			return false;
		if(hasItemInSlot(0) && hasItemInSlot(1)) //Combined Item
		{
			if(RecipesGrinder.getGrinder().getCombinedResult(getItemIdInSlot(0), getItemIdInSlot(1)) != null)
				return canGrindItem(RecipesGrinder.getGrinder().getCombinedResult(getItemIdInSlot(0), getItemIdInSlot(1)));
			else
				return false;
		}			
		else if(hasItemInSlot(0))
		{
			if(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(0)) != null)
				return canGrindItem(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(0)));
			else
				return false;
		}
		else
		{
			if(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(1)) != null)
				return canGrindItem(RecipesGrinder.getGrinder().getSingleResult(getItemIdInSlot(1)));
			else
				return false;
		}
	}
	
	private boolean canGrindItem(ItemStack result)
	{
		if(grinderStacks[3] == null)
			return true;
		return grinderStacks[3].itemID == result.itemID; 
	}
	
	private int getItemIdInSlot(int i)
	{
		if(getItemInSlot(i) != null)
			return getItemInSlot(i).getItem().shiftedIndex;
		return 0;
	}
	
	public void readFromNBT(NBTTagCompound nbttagcompound)
    {
        super.readFromNBT(nbttagcompound);
        NBTTagList nbttaglist = nbttagcompound.getTagList("Items");
        grinderStacks = new ItemStack[getSizeInventory()];
        for(int i = 0; i < nbttaglist.tagCount(); i++)
        {
            NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
            byte byte0 = nbttagcompound1.getByte("Slot");
            if(byte0 >= 0 && byte0 < grinderStacks.length)
            {
            	grinderStacks[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
            }
        }
        grindTime = nbttagcompound.getInteger("GrindTime");
        maxGrindTime = nbttagcompound.getInteger("MaxGrindTime");
        itemGrindTime = nbttagcompound.getInteger("ItemGrindTime");
        isGrinding = nbttagcompound.getBoolean("IsGrinding");
    }

    public void writeToNBT(NBTTagCompound nbttagcompound)
    {
        super.writeToNBT(nbttagcompound);
    	nbttagcompound.setInteger("GrindTime", grindTime);
    	nbttagcompound.setInteger("MaxGrindTime", maxGrindTime);
    	nbttagcompound.setInteger("ItemGrindTime", itemGrindTime);
    	nbttagcompound.setBoolean("IsGrinding", isGrinding);
        NBTTagList nbttaglist = new NBTTagList();
        for(int i = 0; i < grinderStacks.length; i++)
        {
            if(grinderStacks[i] != null)
            {
                NBTTagCompound nbttagcompound1 = new NBTTagCompound();
                nbttagcompound1.setByte("Slot", (byte)i);
                grinderStacks[i].writeToNBT(nbttagcompound1);
                nbttaglist.setTag(nbttagcompound1);
            }
        }

        nbttagcompound.setTag("Items", nbttaglist);
    }
	
	private ItemStack getItemInSlot(int i)
	{
		return grinderStacks[i];
	}
	
	public boolean hasItemInSlot(int i)
	{
		return grinderStacks[i] != null;
	}
	
	public int getGrindTime()
	{
		//200 per item
		if(grinderStacks[2] == null)
			return 1;
		int i = grinderStacks[2].getItem().shiftedIndex;
		
		if (i == Item.coal.shiftedIndex)
			return 800;
		else if (i == mod_pph.charcarbonItem.shiftedIndex)
			return 1600;
		/*else if (i == mod_carbon.charcarbon.shiftedIndex)
			return 1600;*/
		else
			return 1;
	}

}
